package com.gzkemays.demo.config.filter;

import com.gzkemays.jwt.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * @author gzkemays
 * @date 2021/3/18 16:24
 */
@Slf4j
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {

  public JwtAuthorizationFilter(AuthenticationManager authenticationManager) {

    super(authenticationManager);
  }

  @Override
  protected void doFilterInternal(
      HttpServletRequest request, HttpServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    String tokenHeader = request.getHeader("token");
    // 如果请求头中有token，则进行解析，并且设置认证信息
    if (Objects.nonNull(tokenHeader)) {
      SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader));
      //      super.doFilterInternal(request, response, chain);
    }
    chain.doFilter(request, response);
  }

  @Override
  protected void onUnsuccessfulAuthentication(
      HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
      throws IOException {
    response.setCharacterEncoding("utf-8"); // 设置 HttpServletResponse使用utf-8编码
    response.setHeader("Content-Type", "text/html;charset=utf-8"); // 设置响应头的编码
    response.getWriter().write("请先登录");
    log.error(">>>error msg: {}<<<", failed.getMessage());
    super.onUnsuccessfulAuthentication(request, response, failed);
  }

  private UsernamePasswordAuthenticationToken getAuthentication(String token) {
    String username = JwtUtil.getUsername(token);
    if (Objects.nonNull(username)) {
      List<SimpleGrantedAuthority> userRoles = JwtUtil.getUserRole(token);
      return new UsernamePasswordAuthenticationToken(username, null, userRoles);
    }
    return null;
  }
}
